#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#


import json
import os.path
import sys
import traceback
from json import JSONDecodeError
import xml.etree.ElementTree as ET


def json_load_data(json_file_path: str):
    """
    加载json数据
    Args:
        json_file_path ():
    
    Returns:

    """
    try:
        with open(json_file_path, "r", encoding="utf-8") as file:
            return json.load(file)
    
    except JSONDecodeError:
        print(f"json数据 {json_file_path}转字典错误,"
              f"error :{traceback.format_exc()}")


def _ohos_all_part_info(testfwk_path: str):
    """
    Openharmony 所有部件
    Args:
        testfwk_path (): infos_for_testfwk.json

    Returns:

    """
    subsystem_part_infos = json_load_data(testfwk_path)
    part_info_dic = subsystem_part_infos.get("phone", {}).get("subsystem_infos",
                                                              None)
    if not part_info_dic:
        return
    
    part_infos_list = list(part_info_dic.values())
    part_infos = []
    [part_infos.extend(part) for part in part_infos_list]
    return part_infos


def get_part_deps_info(parts_deps: str):
    """
    获取部件依赖关系
    Args:
        parts_deps (): 所查部件名

    Returns:

    """
    part_deps_info = json_load_data(parts_deps)
    return part_deps_info


def obtain_part_dependent(part_deps: str, part_name: str, ohos_part_infos):
    """
    获取该部件被依赖的所有部件

    Args:
        part_deps :
        part_name :
        ohos_part_infos : tdd部件信息

    Returns

    """
    part_deps_info = get_part_deps_info(part_deps)
    part_names = part_deps_info.keys()
    deps_part = []
    if not ohos_part_infos:
        return
    
    for part in part_names:
        if part not in ohos_part_infos:
            continue
        if part_deps_info.get(part) and part_deps_info.get(part).get(
                "components") and part_name in \
                part_deps_info[part]["components"]:
            deps_part.append(part)
    return deps_part


def get_one_part_reverse_deps_info(testfwk_path: str, part_deps: str):
    """
    获取openharmony 所有部件一层反向依赖部件关系
    Args:
        testfwk_path ():
        part_deps ():

    Returns:

    """
    all_part_list = _ohos_all_part_info(testfwk_path)
    if not all_part_list:
        return
    
    deps_part_dic = {}
    for part in all_part_list:
        part_info = obtain_part_dependent(part_deps, part, all_part_list)
        # 筛选不存在依赖不部件的
        # if not part_info:
        #     continue

        deps_part_dic[part] = part_info

    return deps_part_dic



def convert_part_tdd(testfwk_path: str, part_deps: str, required_parts,
                     part_tdd_path: str, xml_path:str):
    """
    部件依赖关系转换
    Args:
        testfwk_path ():
        part_deps ():
        required_parts ():
        part_reverse_deps_path ():
        part_tdd_path ():

    Returns:

    """
    deps_parts = get_one_part_reverse_deps_info(testfwk_path, part_deps)
    required_parts_dic = json_load_data(required_parts)
    deps_keys = deps_parts.keys()
    part_tdd_list = []
    xml_file_path = xml_path  
    tree = ET.parse(xml_file_path)  
    root = tree.getroot()    
    mapping = {}  
    for project in root.findall('project'):
        project_name = project.get('name')
        project_path = project.get('path')
        if project_path is not None:
            last_part = project_path.split('/')[-1]
            mapping[last_part] = project_name
    for part in deps_keys:
        part_test = required_parts_dic[part].get("test", None)
        if not part_test and not deps_parts.get(part, []):
            continue
        elif part_test and not deps_parts.get(part, []):
            name_str = part_test
            target_str = part_test
        elif not part_test and deps_parts.get(part, []):
            inner_kits = required_parts_dic[part].get("inner_kits", None)
            part_str = required_parts_dic[part].get("part", None)
            target_str = ""
            name_str = inner_kits if inner_kits else part_str
        else:
            name_str = part_test
            target_str = part_test
        print(name_str)
        if name_str.split(':')[0].split('/')[-1] in mapping:
            name = mapping[name_str.split(':')[0].split('/')[-1]]
        else:
            continue
        if target_str:
            build_target = target_str.split("(//")[0].split(
                "/", target_str.split("(//")[0].count("/") - 1)[-1]
        else:
            build_target = target_str

        part_info_dic = {
            "name": name,
            "parts": part,
            "buildTarget": build_target
        }
        for deps_part in deps_parts.get(part, []):
            _test = required_parts_dic[deps_part].get("test", None)
            if not _test:
                continue

            build_target = _test.split("(//")[0].split(
                "/", _test.split("(//")[0].count("/") - 1)[-1]
            part_info_dic["buildTarget"] += "," + build_target if \
                part_info_dic["buildTarget"] else build_target

        # 删除部件不存在 test标签 且没有反向依赖部件的
        if not part_info_dic["buildTarget"]:
            continue

        part_tdd_list.append(part_info_dic)
    with open(os.path.join(part_tdd_path, "part_tdd.json"), "w",
              encoding="utf-8") as file:
        json.dump(part_tdd_list, file, indent=4)


if __name__ == '__main__':
    if len(sys.argv) == 6:
        convert_part_tdd(*sys.argv[1:])
    else:
        print("参数异常")
